/*++

Copyright (c) 2007  Microsoft Corporation 

Filename: 

    WMIManager.cs 

Abstract: 

    This file contains definition of WMI Scope Management and Query functions
     
--*/
# region References
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Management;
using System.Text;
# endregion References

namespace DataManager
{
    /// <summary>
    /// WmiManager is used to create the Managemnet Scope and Dynamic queries
    /// </summary>
    public class WmiManager
    {
        #region Variables
        Hashtable columnlist = new Hashtable();
        #endregion Variables

        #region Public Methods
        /// <summary>
        /// Get WMI scope for serverName
        /// </summary>
        /// <param name="ServerName">Server to get scope</param>
        /// <param name="errMsg">Out error message in case of failure</param>
        /// <returns></returns>
        public static ManagementScope GetWmiScope(string serverName, ref string errMsg)
        {            
            // Configure the connection settings.
            ConnectionOptions options = new ConnectionOptions();
            ManagementScope scope;
            if (String.Compare(serverName, Environment.MachineName, true, CultureInfo.CurrentCulture) == 0)
            {
                // Local machine
                scope = new ManagementScope(@"\ROOT\CIMV2", options);
            }
            else
            {
                // Network machine
                scope = new ManagementScope(@"\\" + serverName + @"\root\cimv2", options);
                scope.Options.Impersonation = ImpersonationLevel.Impersonate;
            }

            // Try and connect to the remote (or local) machine.
            try
            {
                scope.Connect();
                return scope;
            }
            catch (ManagementException ex)
            {
                // Failed to authenticate properly.
                errMsg = ex.Message;
                return null;
            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
                // Unable to connect to the RPC service on the remote machine.
                errMsg = ex.Message;
                return null;
            }
            catch (System.UnauthorizedAccessException ex)
            {
                // User not authorized.
                errMsg = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Get WMI scope for serverName with username and password
        /// </summary>
        /// <param name="serverName">Server Name to get scope</param>
        /// <param name="username">UserName to connect to Server</param>
        /// <param name="password">Password to connect to server</param>
        /// <param name="errMsg">Out error message in case of failure</param>
        /// <returns></returns>
        public static ManagementScope GetWmiScope(string serverName, string username, string password, ref string errMsg)
        {
            // Configure the connection settings.
            ConnectionOptions options = new ConnectionOptions();

            ManagementScope scope;

            //Clear error message
            errMsg = string.Empty;

            if (String.Compare(serverName, Environment.MachineName, true, CultureInfo.CurrentCulture) == 0)
            {
                scope = new ManagementScope(@"\ROOT\CIMV2", options);
            }
            else
            {
                options.Username = username;
                options.Password = password;
                options.Impersonation = ImpersonationLevel.Impersonate;
                options.Authentication = AuthenticationLevel.Default;
                options.EnablePrivileges = true;

                scope =
                new ManagementScope("\\\\" + serverName + @"\root\cimv2", options);
            }
            // Try and connect to the remote (or local) machine.
            try
            {
                scope.Connect();
                return scope;
            }
            catch (ManagementException ex)
            {
                // Failed to authenticate properly.
                errMsg = ex.Message;
                return null;
            }
            catch (System.Runtime.InteropServices.COMException ex)
            {
                // Unable to connect to the RPC service on the remote machine.
                errMsg = ex.Message;
                return null;
            }
            catch (System.UnauthorizedAccessException ex)
            {
                // User not authorized.
                 errMsg = ex.Message;
                return null;
            }
        }

        /// <summary>
        /// Create WMI query with parameters and condition specfied
        /// </summary>
        /// <param name="className">Class of WMI to get the data</param>
        /// <param name="condition">Condition for getting data from Class</param>
        /// <param name="columns">Parameters required from the class</param>
        /// <returns></returns>
        public String CreateWmiQuery(String className, String condition, params String[] columns)
        {
            StringBuilder query = new StringBuilder();
            query.Append("Select ");
            if (columns != null)
            {
                foreach (String column in columns)
                {
                    columnlist.Add(column, "");
                    query.Append(column);
                    query.Append(" , ");
                }
                int length = query.Length;
                query.Remove(length - 3, 2);
            }
            query.Append(" from ");
            query.Append(className);
            if (!String.IsNullOrEmpty(condition))
            {
                // If valid condition exist
                query.Append(" where ");
                query.Append(condition);
            }
            return query.ToString();
        }

        /// <summary>
        /// Get the Host data from scope and query
        /// </summary>
        /// <param name="scope">Scope of the Management object</param>
        /// <param name="wmiQueries">Array of all the queries</param>
        /// <param name="serverTable"></param>
        public static void GetHostData(ManagementScope scope, 
            System.Collections.ArrayList wmiQueries,
            ref Hashtable serverTable)
        {
            // Validate in any queries exist
            if (wmiQueries == null)
                return;

            // Validate in server table exist
            if (serverTable == null)
                return;

            foreach (string query in wmiQueries)
            {
                ManagementObjectSearcher moSearch = new ManagementObjectSearcher(scope,
                    new ObjectQuery(query));
                ManagementObjectCollection moReturn = moSearch.Get();
                foreach (ManagementObject mo in moReturn)
                {
                    try
                    {
                        foreach (PropertyData key in mo.Properties)
                        {
                            if (serverTable.Contains(key.Name))
                            {
                                serverTable[key.Name] = serverTable[key.Name] + ";" + key.Value;
                            }
                            else
                            {
                                serverTable.Add(key.Name, key.Value);
                            }
                        }
                    }
                    catch
                    {
                    }
                }
            }
        }
        #endregion Public Methods
    }
}
